package com.generator.util;

import com.generator.constant.MysqlJavaTypeParam;
import com.generator.constant.MysqlJdbcTypeParam;
import com.generator.main.Main;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.apache.velocity.app.VelocityEngine;

import java.io.*;
import java.sql.Connection;
import java.util.*;

public class GeneratorUtil {

    private static boolean getColumnInfo(Map<String, Object> parentMap){
        // 0 = column_name ,1 = data_type, 2 = column_comment, 3 = column_key, 4 = extra
        String querySql = "select column_name,data_type,column_comment,column_key,extra " +
                          "from information_schema.`COLUMNS` " +
                          "where TABLE_NAME='"+ Main.tableName+"' and TABLE_SCHEMA='" + Main.dbName + "'";
        Connection conn = DBUtil.getConnection(Main.url,Main.account,Main.password);
        List columns = DBUtil.getDataBySQL(querySql, conn);
        if(columns==null || columns.size()==0){
            return false;
        }
        //封装查询到的数据
        List<Map<String,Object>> result = new ArrayList<Map<String,Object>>();
        for (Iterator iterator = columns.iterator(); iterator.hasNext(); ) {
            Map<String,Object> columnsMap = new HashMap<String,Object>();
            String[] col = (String[]) iterator.next();
            columnsMap.put("dbName", col[0]);
            columnsMap.put("javaName", StringUtil.underlineToCamel(col[0]));
            columnsMap.put("javaNameUp", StringUtil.underlineToClassName(col[0]));
            columnsMap.put("dbType", MysqlJdbcTypeParam.get(col[1].toUpperCase()));
            columnsMap.put("javaType", MysqlJavaTypeParam.get(col[1].toUpperCase()));
            columnsMap.put("comment",col[2]);
            columnsMap.put("extra",col[4]);
            //添加主键相关
            if("PRI".equalsIgnoreCase(col[3])){
                columnsMap.put("isKey",true);
                parentMap.put("keyDbName",col[0]);
                parentMap.put("keyJavaName",StringUtil.underlineToCamel(col[0]));
                parentMap.put("keyDbType",MysqlJdbcTypeParam.get(col[1].toUpperCase()));
                parentMap.put("keyJavaType", MysqlJavaTypeParam.get(col[1].toUpperCase()));
            }else{
                columnsMap.put("isKey",false);
            }
            //判断类型是否存在
            if(MysqlJavaTypeParam.get(col[1]).equalsIgnoreCase("BigDecimal")){
                parentMap.put("hasBigDecimal",true);
            }
            if(MysqlJavaTypeParam.get(col[1]).equalsIgnoreCase("Date")){
                parentMap.put("hasDate",true);
            }
            result.add(columnsMap);
        }
        parentMap.put("columns", result);
        return true;
    }

    private static Map<String,Object> getTableInfo(){
        // 0 = table_name ,1 = data_type, 2 = table_comment, 3 = engine, 4 = createTime
        String querySql = "select table_name tableName, table_comment tableComment, engine, create_time createTime " +
                " from information_schema.tables " +
                " where table_schema = '"+Main.dbName+"'"+" and table_name = '" + Main.tableName + "'";
        Connection conn = DBUtil.getConnection(Main.url,Main.account,Main.password);
        List columns = DBUtil.getDataBySQL(querySql, conn);
        //封装查询到的数据
        Map<String,Object> result = new  HashMap<String,Object>();
        for (Iterator iterator = columns.iterator(); iterator.hasNext(); ) {
            String[] col = (String[]) iterator.next();
            result.put("tableName",col[0]);
            result.put("comment",col[1]);
            result.put("engine",col[2]);
            result.put("createTime",col[3]);
        }
        return  result;
    }

    public static Map<String, Object> getParamMap(){
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("tableName", Main.tableName);
        map.put("comment", getTableInfo().get("comment"));
        map.put("classNameUp",StringUtil.underlineToClassName(Main.tableName));
        map.put("className",StringUtil.underlineToCamel(Main.tableName));
        map.put("package", Main.packageUrl);
        map.put("author", Main.author);
        map.put("createTime", DateUtil.getCntDtStr(new Date(),"yyyy-MM-dd HH:mm"));
        boolean result = getColumnInfo(map);
        if(!result){
            return null;
        }
        return map;
    }

    public static String createCode(){
        //将获取的表数据封装到模板数据
         Map<String, Object> map = getParamMap();
         if(map==null || map.isEmpty()){
             return "数据库配置错误，请检查!";
         }
        VelocityContext context = new VelocityContext(map);
        //获取模板列表，使用绝对路径
        Properties p = new Properties();
        p.setProperty(VelocityEngine.FILE_RESOURCE_LOADER_PATH, Main.projectPath);
        Velocity.init(p);
        List<String> templates = Main.getTemplates();
        for(String template : templates) {
            System.out.println("template:"+template);
            //渲染模板
            StringWriter sw = new StringWriter();
            Template tpl = Velocity.getTemplate(template, "UTF-8");
            tpl.merge(context, sw);
            //输出文件
            try{
                File fileDir = new File(Main.outputPath);
                File file = new File(Main.outputPath+StringUtil.underlineToClassName(Main.tableName)+template.substring(0,template.length()-3));
                if(!fileDir.exists()){
                    fileDir.mkdir();
                }
                if(!file.exists()){//不存在则创建文件
                     file.createNewFile();
                }

                PrintStream ps = new PrintStream(new FileOutputStream(file));
                ps.append(sw.toString());
            }catch(Exception e){
                e.printStackTrace();
            }
        }
        return "生成成功";
    }
}
